package com.zhangjingcheng.yunyixia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhangjingcheng.yunyixia.constant.MessageConstant;
import com.zhangjingcheng.yunyixia.constant.StatusConstant;
import com.zhangjingcheng.yunyixia.constant.UserConstant;
import com.zhangjingcheng.yunyixia.exception.FileBusinessException;
import com.zhangjingcheng.yunyixia.mapper.ShareMapper;
import com.zhangjingcheng.yunyixia.mapper.StoreMapper;
import com.zhangjingcheng.yunyixia.mapper.UserMapper;
import com.zhangjingcheng.yunyixia.pojo.dto.GetShareFileDTO;
import com.zhangjingcheng.yunyixia.pojo.dto.ShareDTO;
import com.zhangjingcheng.yunyixia.pojo.dto.ShareListDTO;
import com.zhangjingcheng.yunyixia.pojo.entity.Share;
import com.zhangjingcheng.yunyixia.pojo.entity.Store;
import com.zhangjingcheng.yunyixia.pojo.vo.ShareListVO;
import com.zhangjingcheng.yunyixia.pojo.vo.ShareUserVO;
import com.zhangjingcheng.yunyixia.pojo.vo.ShareVO;
import com.zhangjingcheng.yunyixia.result.PageResult;
import com.zhangjingcheng.yunyixia.service.ShareService;
import com.zhangjingcheng.yunyixia.util.StringUtil;
import com.zhangjingcheng.yunyixia.util.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Service
public class ShareServiceImpl implements ShareService {
    @Autowired
    private StoreMapper storeMapper;

    @Autowired
    private ShareMapper shareMapper;

    @Autowired
    private FileServiceImpl fileService;

    @Autowired
    private UserMapper userMapper;


    /**
     * 分享文件
     *
     * @param dto
     * @return
     */
    @Override
    public ShareVO share(ShareDTO dto) {
        // 查询文件
        LambdaQueryWrapper<Store> storeQuery = new LambdaQueryWrapper<Store>()
                .eq(Store::getUserId, ThreadLocalUtil.getId())
                .eq(Store::getFileId, dto.getFileId());

        Store store = storeMapper.selectOne(storeQuery);
        // 如果文件不存在，抛出异常
        if (store == null) {
            throw new FileBusinessException(MessageConstant.FILE_NOT_EXISTS);
        }
        ShareVO shareVO = new ShareVO();
        // 判断用户是否设置了提取码，没有就自动生成
        if (dto.getCodeType() == 1) {
            String code = StringUtil.getRandomString(UserConstant.CODE_LENGTH);
            dto.setCode(code);
        }
        shareVO.setCode(dto.getCode());
        // 判断有效期类型
        LocalDateTime expireTime = switch (dto.getValidType()) {
            case 0 -> LocalDateTime.now().plusDays(1);
            case 1 -> LocalDateTime.now().plusWeeks(1);
            case 2 -> LocalDateTime.now().plusMonths(1);
            case 3 -> LocalDateTime.now().plusYears(999);
            default -> throw new FileBusinessException(MessageConstant.UNKNOWN_ERROR);
        };
        Share share = Share.builder()
                .fileId(dto.getFileId())
                .userId(ThreadLocalUtil.getId())
                .fileName(dto.getFileName())
                .validType(dto.getValidType())
                .expireTime(expireTime)
                .code(dto.getCode())
                .build();
        // 插入数据库
        shareMapper.insert(share);
        shareVO.setId(share.getId());
        return shareVO;
    }

    /**
     * 取消分享
     *
     * @param ids
     */
    @Override
    public void cancelShare(List<Integer> ids) {
        List<Share> shareList = shareMapper.selectByIds(ids);
        if (shareList != null && !shareList.isEmpty()){
            shareList.forEach(share -> {
                if (share != null && share.getUserId().equals(ThreadLocalUtil.getId())) {
                    // 删除数据库记录
                    shareMapper.deleteById(share.getId());
                }
            });
        }
    }

    /**
     * 获取分享文件列表
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult<ShareListVO> list(ShareListDTO dto) {
        Page<ShareListVO> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        page = shareMapper.list(page, dto, ThreadLocalUtil.getId());
        return new PageResult<>(page.getTotal(), page.getRecords());
    }


    /**
     * 获取分享文件
     *
     * @param dto
     */
    @Override
    public void getShareFile(GetShareFileDTO dto, HttpServletResponse response) {
        // 查询分享记录
        LambdaQueryWrapper<Share> queryWrapper = new LambdaQueryWrapper<Share>()
                .eq(Share::getId, dto.getId())
                .eq(Share::getCode, dto.getCode());
        Share share = shareMapper.selectOne(queryWrapper);
        if (share == null){
            throw new FileBusinessException(MessageConstant.FILE_NOT_EXISTS);
        }
        // 判断用户是否被禁用
        if (Objects.equals(userMapper.selectById(share.getUserId()).getStatus(), StatusConstant.DISABLE)){
            throw new FileBusinessException(MessageConstant.ACCOUNT_LOCKED);
        }
        if (share.getExpireTime().isBefore(LocalDateTime.now())){
            //删除分享信息
            shareMapper.deleteById(share.getId());
            throw new FileBusinessException(MessageConstant.FILE_NOT_EXISTS);
        }
        // 下载文件
        fileService.download(share.getFileId(), response);
    }

    /**
     * 获取分享文件信息
     *
     * @param id
     * @return
     */
    @Override
    public ShareUserVO getShareFileInfo(Integer id) {
        return shareMapper.getShareFileInfo(id);
    }

    /**
     * 获取下载链接
     *
     * @param id
     * @return
     */
    @Override
    public String getDownloadCode(Integer id) {
        Share share = shareMapper.selectById(id);
        return share.getCode();
    }
}